package top.lixunda.demo.seata.order.rest;

import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import top.lixunda.demo.seata.common.controller.MessageObject;
import top.lixunda.demo.seata.common.entity.DbAccount;
import top.lixunda.demo.seata.common.entity.DbGood;
import top.lixunda.demo.seata.common.entity.DbOrder;
import top.lixunda.demo.seata.common.exception.AppException;
import top.lixunda.demo.seata.feign.AccountClient;
import top.lixunda.demo.seata.feign.GoodClient;
import top.lixunda.demo.seata.order.service.IDbOrderService;

import java.util.List;

/**
 * @author LiXunda
 * @version time:2019/10/25 13:10
 */
@SuppressWarnings("Duplicates")
@RestController
@Slf4j
@RequestMapping("/order")
public class OrderController {

    private final IDbOrderService orderService;

    private final AccountClient accountClient;

    private final GoodClient goodClient;

    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
    @Autowired
    public OrderController(IDbOrderService orderService, AccountClient accountClient, GoodClient goodClient) {
        this.orderService = orderService;
        this.accountClient = accountClient;
        this.goodClient = goodClient;
    }

    /**
     * 提价订单消息
     *
     * @param goodId    商品id
     * @param accountId 用户id
     * @param count     商品数量
     * @return MessageObject
     */
    @GetMapping("submitOrder")
    @GlobalTransactional
    public MessageObject<DbOrder> submitOrder(Integer goodId, Integer accountId, Integer count) {
        //1. 获取上商品信息
        DbGood good = goodClient.getGoodById(goodId).getObject();
        System.out.println("-----------------------" + good + "-----------------------");
        //2. 计算总价格
        double allPrice = good.getGPrice().doubleValue() * count;
        System.out.println("-----------------------" + allPrice + "-----------------------");
        //3. 扣减用户余额
        accountClient.deduction(accountId, allPrice);

        //5. 生成订单
        DbOrder order = new DbOrder();
        order.setOAccountId(accountId);
        order.setOGoodId(goodId);
        order.setOPrice((int) Math.round(allPrice));
        System.out.println("-----------------------" + order + "-----------------------");
        boolean success = orderService.save(order);
        System.out.println("-----------------------" + order + "-----------------------");
        if (!success) {
            throw AppException.message("提交订单失败");
        }

        //4. 扣减商品数量
        goodClient.reduceStock(goodId, count);
        return MessageObject.success(order);
    }

    /**
     * 上级微服务处理了异常，下级微服务正常抛出异常
     *
     * @param goodId    商品id
     * @param accountId 用户id
     * @param count     商品数量
     * @return MessageObject
     */
    @GetMapping("submitOrderNoException")
    @GlobalTransactional
    public MessageObject<DbOrder> submitOrderNoException(Integer goodId, Integer accountId, Integer count) {
        try {
            return submitOrder(goodId, accountId, count);
        } catch (Exception e) {
            return MessageObject.error("发生异常", null);
        }
    }

    /**
     * 自定义异常处理
     *
     * @param e AppException自定义异常
     * @return MessageObject
     */
    @ExceptionHandler(AppException.class)
    public MessageObject<String> appException(AppException e) {
        e.printStackTrace();
        return MessageObject.error("发生了异常：" + e.getMessage());
    }

    /**
     * 这里抛出自己的异常，可以进行回退
     *
     * @param goodId    商品id
     * @param accountId 用户id
     * @param count     商品数量
     * @return MessageObject
     */
    @GetMapping("submitOrderExceptionHandler")
    @GlobalTransactional
    public MessageObject<DbOrder> submitOrderExceptionHandler(Integer goodId, Integer accountId, Integer count) {
        try {
            return submitOrder(goodId, accountId, count);
        } catch (Exception e) {
            throw new AppException("发生了异常");
        }
    }

    /**
     * 查询所有订单信息
     *
     * @return DBOrder 的List
     */
    @GetMapping("/queryAll")
    public MessageObject<List<DbOrder>> queryAll() {
        return MessageObject.success(orderService.list());
    }

    /**
     * 测试feign使用
     *
     * @return MessageObject
     */
    @GetMapping("/queryAccountAll")
    public MessageObject<List<DbAccount>> queryAccountAll() {
        return accountClient.queryAll();
    }

    /**
     * 测试feign使用
     *
     * @return JSON
     */
    @GetMapping("/queryGoodAll")
    public MessageObject<List<DbGood>> queryGoodAll() {
        return goodClient.queryAll();
    }

}
